/*-------------------------------------------------------------------------
 *
 * varbit.c
 *	  SQL 数据类型 BIT() 和 BIT VARYING() 的函数。
 *
 * 数据结构包含以下元素：
 *   header  -- 整个数据结构的长度（包括头部）
 *              以字节为单位（对于所有可变长度数据类型都是如此）
 *   data section -- 位数据结构的私有数据部分
 *     bitlength -- 位串的长度（以位为单位）
 *     bitdata   -- 位串，最高有效字节优先
 *
 * bitdata 向量的长度应始终正好与给定的 bitlength 所需的字节数相同。
 * 如果 bitlength 不是 8 的倍数，最后一个字节的额外低位填充位必须是零。
 *
 * attypmod 被定义为位串的长度（以位为单位），或者对于可变位而言为最大长度。
 *
 * 代码最初由 Adriaan Joubert 提供。
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  src/backend/utils/adt/varbit.c
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

#include "access/htup_details.h"
#include "common/int.h"
#include "libpq/pqformat.h"
#include "nodes/nodeFuncs.h"
#include "nodes/supportnodes.h"
#include "port/pg_bitutils.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/varbit.h"

#define HEXDIG(z)	 ((z)<10 ? ((z)+'0') : ((z)-10+'A'))

 /* 屏蔽位字符串最后一个字节中应该为零的任何位 */
#define VARBIT_PAD(vb) \
	do { \
		int32	fc_pad_ = VARBITPAD(vb); \
		Assert(fc_pad_ >= 0 && fc_pad_ < BITS_PER_BYTE); \
		if (fc_pad_ > 0) \
			*(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << fc_pad_; \
	} while (0)

 /*
 * 许多函数逐字节工作，因此它们有一个指针指向
 * 最后一个加一字节，这节省了一两个周期。
 */
#define VARBIT_PAD_LAST(vb, ptr) \
	do { \
		int32	fc_pad_ = VARBITPAD(vb); \
		Assert(fc_pad_ >= 0 && fc_pad_ < BITS_PER_BYTE); \
		if (fc_pad_ > 0) \
			*((ptr) - 1) &= BITMASK << fc_pad_; \
	} while (0)

 /* 断言位字符串的适当填充 */
#ifdef USE_ASSERT_CHECKING
#define VARBIT_CORRECTLY_PADDED(vb) \
	do { \
		int32	fc_pad_ = VARBITPAD(vb); \
		Assert(fc_pad_ >= 0 && fc_pad_ < BITS_PER_BYTE); \
		Assert(fc_pad_ == 0 || \
			   (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << fc_pad_)) == 0); \
	} while (0)
#else
#define VARBIT_CORRECTLY_PADDED(vb) ((void) 0)
#endif

static VarBit *fc_bit_catenate(VarBit *fc_arg1, VarBit *fc_arg2);
static VarBit *fc_bitsubstring(VarBit *fc_arg, int32 fc_s, int32 fc_l,
							bool fc_length_not_specified);
static VarBit *fc_bit_overlay(VarBit *fc_t1, VarBit *fc_t2, int fc_sp, int fc_sl);


 /*
 * bittypmodin 和 varbittypmodin 的公共代码
 */
static int32 fc_anybit_typmodin(ArrayType *fc_ta, const char *fc_typename)
{
	int32		fc_typmod;
	int32	   *fc_tl;
	int			fc_n;

	fc_tl = ArrayGetIntegerTypmods(fc_ta, &fc_n);

	 /*
	 * 我们对这里的错误消息不是太紧张，因为语法
	 * 不应该允许 BIT 的修饰符数量错误
	 */
	if (fc_n != 1)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid type modifier")));

	if (*fc_tl < 1)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("length for type %s must be at least 1",
						fc_typename)));
	if (*fc_tl > (MaxAttrSize * BITS_PER_BYTE))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("length for type %s cannot exceed %d",
						fc_typename, MaxAttrSize * BITS_PER_BYTE)));

	fc_typmod = *fc_tl;

	return fc_typmod;
}

/*
 * bittypmodout 和 varbittypmodout 的公共代码
 */
static char * fc_anybit_typmodout(int32 fc_typmod)
{
	char	   *fc_res = (char *) palloc(64);

	if (fc_typmod >= 0)
		snprintf(fc_res, 64, "(%d)", fc_typmod);
	else
		*fc_res = '\0';

	return fc_res;
}


/*
 * bit_in -
 *	  将字符字符串转换为位字符串的内部表示。
 *		  长度由所需的位数加上 VARHDRSZ 字节或由 atttypmod 确定。
 */
Datum bit_in(PG_FUNCTION_ARGS)
{
	char	   *fc_input_string = PG_GETARG_CSTRING(0);

#ifdef NOT_USED
	Oid			fc_typelem = PG_GETARG_OID(1);
#endif
	int32		fc_atttypmod = PG_GETARG_INT32(2);
	VarBit	   *fc_result;			/* 结果位字符串			  */
	char	   *fc_sp;				/* 指向字符字符串的指针  */
	bits8	   *fc_r;				/* 指向结果的指针 */
	int			fc_len,			/* 整个数据结构的长度 */
				fc_bitlen,			/* 位字符串中的位数   */
				fc_slen;			/* 输入字符串的长度		  */
	bool		fc_bit_not_hex;	/* false = 十六进制字符串  true = 位字符串 */
	int			fc_bc;
	bits8		fc_x = 0;

	/* 检查第一个字符是否是 b 或 x */
	if (fc_input_string[0] == 'b' || fc_input_string[0] == 'B')
	{
		fc_bit_not_hex = true;
		fc_sp = fc_input_string + 1;
	}
	else if (fc_input_string[0] == 'x' || fc_input_string[0] == 'X')
	{
		fc_bit_not_hex = false;
		fc_sp = fc_input_string + 1;
	}
	else
	{
		/*
		 * 否则就是二进制。这允许像 cast('1001' as bit)
		 * 透明地工作。
		 */
		fc_bit_not_hex = true;
		fc_sp = fc_input_string;
	}

	/*
	 * 从输入字符串确定位长度。MaxAllocSize 确保常规
	 * 输入足够小，但我们必须检查十六进制输入。
	 */
	fc_slen = strlen(fc_sp);
	if (fc_bit_not_hex)
		fc_bitlen = fc_slen;
	else
	{
		if (fc_slen > VARBITMAXLEN / 4)
			ereport(ERROR,
					(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
					 errmsg("bit string length exceeds the maximum allowed (%d)",
							VARBITMAXLEN)));
		fc_bitlen = fc_slen * 4;
	}

	/*
	 * 有时 atttypmod 并未提供。如果它被提供，我们需要
	 * 确保位字符串适合。
	 */
	if (fc_atttypmod <= 0)
		fc_atttypmod = fc_bitlen;
	else if (fc_bitlen != fc_atttypmod)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
				 errmsg("bit string length %d does not match type bit(%d)",
						fc_bitlen, fc_atttypmod)));

	fc_len = VARBITTOTALLEN(fc_atttypmod);
	/* 设置为 0，以便 *r 始终初始化，字符串是零填充 */
	fc_result = (VarBit *) palloc0(fc_len);
	SET_VARSIZE(fc_result, fc_len);
	VARBITLEN(fc_result) = fc_atttypmod;

	fc_r = VARBITS(fc_result);
	if (fc_bit_not_hex)
	{
		/* 解析字符串的位表示 */
		/* 我们知道它适合，因为 bitlen 已与 atttypmod 比较 */
		fc_x = HIGHBIT;
		for (; *fc_sp; fc_sp++)
		{
			if (*fc_sp == '1')
				*fc_r |= fc_x;
			else if (*fc_sp != '0')
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
						 errmsg("\"%.*s\" is not a valid binary digit",
								pg_mblen(fc_sp), fc_sp)));

			fc_x >>= 1;
			if (fc_x == 0)
			{
				fc_x = HIGHBIT;
				fc_r++;
			}
		}
	}
	else
	{
		/* 解析字符串的十六进制表示 */
		for (fc_bc = 0; *fc_sp; fc_sp++)
		{
			if (*fc_sp >= '0' && *fc_sp <= '9')
				fc_x = (bits8) (*fc_sp - '0');
			else if (*fc_sp >= 'A' && *fc_sp <= 'F')
				fc_x = (bits8) (*fc_sp - 'A') + 10;
			else if (*fc_sp >= 'a' && *fc_sp <= 'f')
				fc_x = (bits8) (*fc_sp - 'a') + 10;
			else
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
						 errmsg("\"%.*s\" is not a valid hexadecimal digit",
								pg_mblen(fc_sp), fc_sp)));

			if (fc_bc)
			{
				*fc_r++ |= fc_x;
				fc_bc = 0;
			}
			else
			{
				*fc_r = fc_x << 4;
				fc_bc = 1;
			}
		}
	}

	PG_RETURN_VARBIT_P(fc_result);
}


Datum bit_out(PG_FUNCTION_ARGS)
{
#if 1
	/* 与 varbit 输出相同 */
	return varbit_out(fcinfo);
#else

	/*
	 * 这是打印十六进制字符串的方式，以防有人想要
	 * 编写格式化函数。
	 */
	VarBit	   *s = PG_GETARG_VARBIT_P(0);
	char	   *result,
			   *r;
	bits8	   *sp;
	int			i,
				len,
				bitlen;

	/* 帮助捕捉任何没有正确填充的位函数的断言 */
	VARBIT_CORRECTLY_PADDED(s);

	bitlen = VARBITLEN(s);
	len = (bitlen + 3) / 4;
	result = (char *) palloc(len + 2);
	sp = VARBITS(s);
	r = result;
	*r++ = 'X';
	/* 我们通过知道我们存储的是填充的完整字节来作弊 */
	for (i = 0; i < len; i += 2, sp++)
	{
		*r++ = HEXDIG((*sp) >> 4);
		*r++ = HEXDIG((*sp) & 0xF);
	}

	/*
	 * 如果我们打印了一个不再是位字符串的十六进制数字，退回一步
	 */
	if (i > len)
		r--;
	*r = '\0';

	PG_RETURN_CSTRING(result);
#endif
}

/*
 *		bit_recv			- 将外部二进制格式转换为位
 */
Datum bit_recv(PG_FUNCTION_ARGS)
{
	StringInfo	fc_buf = (StringInfo) PG_GETARG_POINTER(0);

#ifdef NOT_USED
	Oid			fc_typelem = PG_GETARG_OID(1);
#endif
	int32		fc_atttypmod = PG_GETARG_INT32(2);
	VarBit	   *fc_result;
	int			fc_len,
				fc_bitlen;

	fc_bitlen = pq_getmsgint(fc_buf, sizeof(int32));
	if (fc_bitlen < 0 || fc_bitlen > VARBITMAXLEN)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
				 errmsg("invalid length in external bit string")));

	/*
	 * 有时 atttypmod 并未提供。如果它被提供，我们需要
	 * 确保位字符串适合。
	 */
	if (fc_atttypmod > 0 && fc_bitlen != fc_atttypmod)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
				 errmsg("bit string length %d does not match type bit(%d)",
						fc_bitlen, fc_atttypmod)));

	fc_len = VARBITTOTALLEN(fc_bitlen);
	fc_result = (VarBit *) palloc(fc_len);
	SET_VARSIZE(fc_result, fc_len);
	VARBITLEN(fc_result) = fc_bitlen;

	pq_copymsgbytes(fc_buf, (char *) VARBITS(fc_result), VARBITBYTES(fc_result));

	/* 确保最后一个字节正确地零填充 */
	VARBIT_PAD(fc_result);

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 *		bit_send			- 将位转换为二进制格式
 */
Datum bit_send(PG_FUNCTION_ARGS)
{
	/* 与 varbit_send 完全相同，因此共享代码 */
	return varbit_send(fcinfo);
}

/*
 * bit()
 * 将 bit() 类型转换为特定的内部长度。
 * len 是列定义中指定的位长度。
 *
 * 如果进行隐式转换，当源数据长度错误时引发错误。
 * 如果进行显式转换，则静默截断或零填充到指定长度。
 */
Datum bit(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);
	int32		fc_len = PG_GETARG_INT32(1);
	bool		fc_isExplicit = PG_GETARG_BOOL(2);
	VarBit	   *fc_result;
	int			fc_rlen;

	/* 如果 typmod 无效或提供的数据已匹配，则不进行操作 */
	if (fc_len <= 0 || fc_len > VARBITMAXLEN || fc_len == VARBITLEN(fc_arg))
		PG_RETURN_VARBIT_P(fc_arg);

	if (!fc_isExplicit)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
				 errmsg("bit string length %d does not match type bit(%d)",
						VARBITLEN(fc_arg), fc_len)));

	fc_rlen = VARBITTOTALLEN(fc_len);
	/* 设置为 0，以便字符串是零填充 */
	fc_result = (VarBit *) palloc0(fc_rlen);
	SET_VARSIZE(fc_result, fc_rlen);
	VARBITLEN(fc_result) = fc_len;

	memcpy(VARBITS(fc_result), VARBITS(fc_arg),
		   Min(VARBITBYTES(fc_result), VARBITBYTES(fc_arg)));

	/*
	 * 如果需要，确保最后一个字节被零填充。 如果源数据比目标长度短，这将是无用的但安全的
	 * （我们假设源数据的最后一个字节本身被正确地零填充）。
	 */
	VARBIT_PAD(fc_result);

	PG_RETURN_VARBIT_P(fc_result);
}

Datum bittypmodin(PG_FUNCTION_ARGS)
{
	ArrayType  *fc_ta = PG_GETARG_ARRAYTYPE_P(0);

	PG_RETURN_INT32(fc_anybit_typmodin(fc_ta, "bit"));
}

Datum bittypmodout(PG_FUNCTION_ARGS)
{
	int32		fc_typmod = PG_GETARG_INT32(0);

	PG_RETURN_CSTRING(fc_anybit_typmodout(fc_typmod));
}


/*
 * varbit_in -
 *	  将字符串转换为位字符串的内部表示。
 *		这与 bit_in 相同，除了 atttypmod 被视为最大长度，而不是强制位字符串的确切长度。
 */
Datum varbit_in(PG_FUNCTION_ARGS)
{
	char	   *fc_input_string = PG_GETARG_CSTRING(0);

#ifdef NOT_USED
	Oid			fc_typelem = PG_GETARG_OID(1);
#endif
	int32		fc_atttypmod = PG_GETARG_INT32(2);
	VarBit	   *fc_result;			/* 结果位字符串			  */
	char	   *fc_sp;				/* 指向字符字符串的指针  */
	bits8	   *fc_r;				/* 指向结果的指针 */
	int			fc_len,			/* 整个数据结构的长度 */
				fc_bitlen,			/* 位字符串中的位数   */
				fc_slen;			/* 输入字符串的长度		  */
	bool		fc_bit_not_hex;	/* false = 十六进制字符串  true = 位字符串 */
	int			fc_bc;
	bits8		fc_x = 0;

	/* 检查第一个字符是否是 b 或 x */
	if (fc_input_string[0] == 'b' || fc_input_string[0] == 'B')
	{
		fc_bit_not_hex = true;
		fc_sp = fc_input_string + 1;
	}
	else if (fc_input_string[0] == 'x' || fc_input_string[0] == 'X')
	{
		fc_bit_not_hex = false;
		fc_sp = fc_input_string + 1;
	}
	else
	{
		fc_bit_not_hex = true;
		fc_sp = fc_input_string;
	}

	/*
	 * 从输入字符串确定位长度。MaxAllocSize 确保常规
	 * 输入足够小，但我们必须检查十六进制输入。
	 */
	fc_slen = strlen(fc_sp);
	if (fc_bit_not_hex)
		fc_bitlen = fc_slen;
	else
	{
		if (fc_slen > VARBITMAXLEN / 4)
			ereport(ERROR,
					(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
					 errmsg("bit string length exceeds the maximum allowed (%d)",
							VARBITMAXLEN)));
		fc_bitlen = fc_slen * 4;
	}

	/*
	 * 有时 atttypmod 并未提供。如果它被提供，我们需要
	 * 确保位字符串适合。
	 */
	if (fc_atttypmod <= 0)
		fc_atttypmod = fc_bitlen;
	else if (fc_bitlen > fc_atttypmod)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
				 errmsg("bit string too long for type bit varying(%d)",
						fc_atttypmod)));

	fc_len = VARBITTOTALLEN(fc_bitlen);
	/* 设置为 0，以便 *r 始终初始化，字符串是零填充 */
	fc_result = (VarBit *) palloc0(fc_len);
	SET_VARSIZE(fc_result, fc_len);
	VARBITLEN(fc_result) = Min(fc_bitlen, fc_atttypmod);

	fc_r = VARBITS(fc_result);
	if (fc_bit_not_hex)
	{
		/* 解析字符串的位表示 */
		/* 我们知道它适合，因为 bitlen 已与 atttypmod 比较 */
		fc_x = HIGHBIT;
		for (; *fc_sp; fc_sp++)
		{
			if (*fc_sp == '1')
				*fc_r |= fc_x;
			else if (*fc_sp != '0')
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
						 errmsg("\"%.*s\" is not a valid binary digit",
								pg_mblen(fc_sp), fc_sp)));

			fc_x >>= 1;
			if (fc_x == 0)
			{
				fc_x = HIGHBIT;
				fc_r++;
			}
		}
	}
	else
	{
		/* 解析字符串的十六进制表示 */
		for (fc_bc = 0; *fc_sp; fc_sp++)
		{
			if (*fc_sp >= '0' && *fc_sp <= '9')
				fc_x = (bits8) (*fc_sp - '0');
			else if (*fc_sp >= 'A' && *fc_sp <= 'F')
				fc_x = (bits8) (*fc_sp - 'A') + 10;
			else if (*fc_sp >= 'a' && *fc_sp <= 'f')
				fc_x = (bits8) (*fc_sp - 'a') + 10;
			else
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
						 errmsg("\"%.*s\" is not a valid hexadecimal digit",
								pg_mblen(fc_sp), fc_sp)));

			if (fc_bc)
			{
				*fc_r++ |= fc_x;
				fc_bc = 0;
			}
			else
			{
				*fc_r = fc_x << 4;
				fc_bc = 1;
			}
		}
	}

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 * varbit_out -
 *	  将字符串按位打印以准确保留长度
 *
 * XXX varbit_recv() 和 hex 输入到 varbit_in() 可以加载一个此代码无法发出的值。
 * 考虑对这些值使用十六进制输出。
 */
Datum varbit_out(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_s = PG_GETARG_VARBIT_P(0);
	char	   *fc_result,
			   *fc_r;
	bits8	   *fc_sp;
	bits8		fc_x;
	int			fc_i,
				fc_k,
				fc_len;

	/* 帮助捕捉任何没有正确填充的位函数的断言 */
	VARBIT_CORRECTLY_PADDED(fc_s);

	fc_len = VARBITLEN(fc_s);
	fc_result = (char *) palloc(fc_len + 1);
	fc_sp = VARBITS(fc_s);
	fc_r = fc_result;
	for (fc_i = 0; fc_i <= fc_len - BITS_PER_BYTE; fc_i += BITS_PER_BYTE, fc_sp++)
	{
		/* 打印完整字节 */
		fc_x = *fc_sp;
		for (fc_k = 0; fc_k < BITS_PER_BYTE; fc_k++)
		{
			*fc_r++ = IS_HIGHBIT_SET(fc_x) ? '1' : '0';
			fc_x <<= 1;
		}
	}
	if (fc_i < fc_len)
	{
		/* 打印最后一个部分字节 */
		fc_x = *fc_sp;
		for (fc_k = fc_i; fc_k < fc_len; fc_k++)
		{
			*fc_r++ = IS_HIGHBIT_SET(fc_x) ? '1' : '0';
			fc_x <<= 1;
		}
	}
	*fc_r = '\0';

	PG_RETURN_CSTRING(fc_result);
}

/*
 *		varbit_recv			- 将外部二进制格式转换为 varbit
 *
 * 外部格式为 bitlen，作为 int32，然后是字节数组。
 */
Datum varbit_recv(PG_FUNCTION_ARGS)
{
	StringInfo	fc_buf = (StringInfo) PG_GETARG_POINTER(0);

#ifdef NOT_USED
	Oid			fc_typelem = PG_GETARG_OID(1);
#endif
	int32		fc_atttypmod = PG_GETARG_INT32(2);
	VarBit	   *fc_result;
	int			fc_len,
				fc_bitlen;

	fc_bitlen = pq_getmsgint(fc_buf, sizeof(int32));
	if (fc_bitlen < 0 || fc_bitlen > VARBITMAXLEN)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
				 errmsg("invalid length in external bit string")));

	/*
	 * 有时 atttypmod 并未提供。如果它被提供，我们需要
	 * 确保位字符串适合。
	 */
	if (fc_atttypmod > 0 && fc_bitlen > fc_atttypmod)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
				 errmsg("bit string too long for type bit varying(%d)",
						fc_atttypmod)));

	fc_len = VARBITTOTALLEN(fc_bitlen);
	fc_result = (VarBit *) palloc(fc_len);
	SET_VARSIZE(fc_result, fc_len);
	VARBITLEN(fc_result) = fc_bitlen;

	pq_copymsgbytes(fc_buf, (char *) VARBITS(fc_result), VARBITBYTES(fc_result));

	/* 确保最后一个字节正确地零填充 */
	VARBIT_PAD(fc_result);

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 *		varbit_send			- 将 varbit 转换为二进制格式
 */
Datum varbit_send(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_s = PG_GETARG_VARBIT_P(0);
	StringInfoData fc_buf;

	pq_begintypsend(&fc_buf);
	pq_sendint32(&fc_buf, VARBITLEN(fc_s));
	pq_sendbytes(&fc_buf, (char *) VARBITS(fc_s), VARBITBYTES(fc_s));
	PG_RETURN_BYTEA_P(pq_endtypsend(&fc_buf));
}

/*
 * varbit_support()
 *
 * varbit() 长度强制函数的规划器支持函数。
 *
 * 目前，我们可以做的唯一有趣的事情是扁平化设置新最大长度 >= 先前最大长度的调用。
 * 我们可以忽略 isExplicit 参数，因为它仅影响截断情况。
 */
Datum varbit_support(PG_FUNCTION_ARGS)
{
	Node	   *fc_rawreq = (Node *) PG_GETARG_POINTER(0);
	Node	   *fc_ret = NULL;

	if (IsA(fc_rawreq, SupportRequestSimplify))
	{
		SupportRequestSimplify *fc_req = (SupportRequestSimplify *) fc_rawreq;
		FuncExpr   *fc_expr = fc_req->fcall;
		Node	   *fc_typmod;

		Assert(list_length(fc_expr->args) >= 2);

		fc_typmod = (Node *) lsecond(fc_expr->args);

		if (IsA(fc_typmod, Const) && !((Const *) fc_typmod)->constisnull)
		{
			Node	   *fc_source = (Node *) linitial(fc_expr->args);
			int32		fc_new_typmod = DatumGetInt32(((Const *) fc_typmod)->constvalue);
			int32		fc_old_max = exprTypmod(fc_source);
			int32		fc_new_max = fc_new_typmod;

			/* 注意：varbit() 将 typmod 0 视为无效，因此我们也如此处理 */
			if (fc_new_max <= 0 || (fc_old_max > 0 && fc_old_max <= fc_new_max))
				fc_ret = relabel_to_typmod(fc_source, fc_new_typmod);
		}
	}

	PG_RETURN_POINTER(fc_ret);
}

/*
 * varbit()
 * 将 varbit() 类型转换为特定内部长度。
 * len 是列定义中指定的最大位长度。
 *
 * 如果进行隐式转换，当源数据过长时引发错误。
 * 如果进行显式转换，则静默截断到最大长度。
 */
Datum varbit(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);
	int32		fc_len = PG_GETARG_INT32(1);
	bool		fc_isExplicit = PG_GETARG_BOOL(2);
	VarBit	   *fc_result;
	int			fc_rlen;

	/* 如果 typmod 无效或提供的数据已匹配，则不进行操作 */
	if (fc_len <= 0 || fc_len >= VARBITLEN(fc_arg))
		PG_RETURN_VARBIT_P(fc_arg);

	if (!fc_isExplicit)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
				 errmsg("bit string too long for type bit varying(%d)",
						fc_len)));

	fc_rlen = VARBITTOTALLEN(fc_len);
	fc_result = (VarBit *) palloc(fc_rlen);
	SET_VARSIZE(fc_result, fc_rlen);
	VARBITLEN(fc_result) = fc_len;

	memcpy(VARBITS(fc_result), VARBITS(fc_arg), VARBITBYTES(fc_result));

	/* 确保最后一个字节正确地零填充 */
	VARBIT_PAD(fc_result);

	PG_RETURN_VARBIT_P(fc_result);
}

Datum varbittypmodin(PG_FUNCTION_ARGS)
{
	ArrayType  *fc_ta = PG_GETARG_ARRAYTYPE_P(0);

	PG_RETURN_INT32(fc_anybit_typmodin(fc_ta, "varbit"));
}

Datum varbittypmodout(PG_FUNCTION_ARGS)
{
	int32		fc_typmod = PG_GETARG_INT32(0);

	PG_RETURN_CSTRING(fc_anybit_typmodout(fc_typmod));
}


/*
 * 比较运算符
 *
 * 对于位字符串，我们只需要一组比较运算符，因为零填充和可变位字符串的长度
 * 以相同的方式存储。
 *
 * 请注意，标准对零填充位字符串和可变位字符串之间的比较并不明确。
 * 如果将相同的值写入与可变位字符串相同的零填充位字符串中，但零填充位字符串的
 * 长度更大，它将更大。
 *
 * 位字符串开头的零不能简单忽略，因为它们可能是位字符串的一部分并可能具有重要意义。
 *
 * 注意：btree 索引需要这些例程不泄漏内存；因此，
 * 小心释放调味数据的工作副本。大多数地方不需要这样小心。
 */

/*
 * bit_cmp
 *
 * 比较两个位字符串，并根据第一个字符串是否小于、等于或大于第二个字符串返回 <0, 0, >0。
 * 所有位都被考虑，额外的零位可能使一个字符串比另一个更小/更大，即使它们的零填充值相同。
 */
static int32 fc_bit_cmp(VarBit *fc_arg1, VarBit *fc_arg2)
{
	int			fc_bitlen1,
				fc_bytelen1,
				fc_bitlen2,
				fc_bytelen2;
	int32		fc_cmp;

	fc_bytelen1 = VARBITBYTES(fc_arg1);
	fc_bytelen2 = VARBITBYTES(fc_arg2);

	fc_cmp = memcmp(VARBITS(fc_arg1), VARBITS(fc_arg2), Min(fc_bytelen1, fc_bytelen2));
	if (fc_cmp == 0)
	{
		fc_bitlen1 = VARBITLEN(fc_arg1);
		fc_bitlen2 = VARBITLEN(fc_arg2);
		if (fc_bitlen1 != fc_bitlen2)
			fc_cmp = (fc_bitlen1 < fc_bitlen2) ? -1 : 1;
	}
	return fc_cmp;
}

Datum biteq(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	bool		fc_result;
	int			fc_bitlen1,
				fc_bitlen2;

	fc_bitlen1 = VARBITLEN(fc_arg1);
	fc_bitlen2 = VARBITLEN(fc_arg2);

	/* 不同长度输入的快速路径 */
	if (fc_bitlen1 != fc_bitlen2)
		fc_result = false;
	else
		fc_result = (fc_bit_cmp(fc_arg1, fc_arg2) == 0);

	PG_FREE_IF_COPY(fc_arg1, 0);
	PG_FREE_IF_COPY(fc_arg2, 1);

	PG_RETURN_BOOL(fc_result);
}

Datum bitne(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	bool		fc_result;
	int			fc_bitlen1,
				fc_bitlen2;

	fc_bitlen1 = VARBITLEN(fc_arg1);
	fc_bitlen2 = VARBITLEN(fc_arg2);

	/* 不同长度输入的快速路径 */
	if (fc_bitlen1 != fc_bitlen2)
		fc_result = true;
	else
		fc_result = (fc_bit_cmp(fc_arg1, fc_arg2) != 0);

	PG_FREE_IF_COPY(fc_arg1, 0);
	PG_FREE_IF_COPY(fc_arg2, 1);

	PG_RETURN_BOOL(fc_result);
}

Datum bitlt(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	bool		fc_result;

	fc_result = (fc_bit_cmp(fc_arg1, fc_arg2) < 0);

	PG_FREE_IF_COPY(fc_arg1, 0);
	PG_FREE_IF_COPY(fc_arg2, 1);

	PG_RETURN_BOOL(fc_result);
}

Datum bitle(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	bool		fc_result;

	fc_result = (fc_bit_cmp(fc_arg1, fc_arg2) <= 0);

	PG_FREE_IF_COPY(fc_arg1, 0);
	PG_FREE_IF_COPY(fc_arg2, 1);

	PG_RETURN_BOOL(fc_result);
}

Datum bitgt(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	bool		fc_result;

	fc_result = (fc_bit_cmp(fc_arg1, fc_arg2) > 0);

	PG_FREE_IF_COPY(fc_arg1, 0);
	PG_FREE_IF_COPY(fc_arg2, 1);

	PG_RETURN_BOOL(fc_result);
}

Datum bitge(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	bool		fc_result;

	fc_result = (fc_bit_cmp(fc_arg1, fc_arg2) >= 0);

	PG_FREE_IF_COPY(fc_arg1, 0);
	PG_FREE_IF_COPY(fc_arg2, 1);

	PG_RETURN_BOOL(fc_result);
}

Datum bitcmp(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	int32		fc_result;

	fc_result = fc_bit_cmp(fc_arg1, fc_arg2);

	PG_FREE_IF_COPY(fc_arg1, 0);
	PG_FREE_IF_COPY(fc_arg2, 1);

	PG_RETURN_INT32(fc_result);
}

/*
 * bitcat
 * 位字符串的连接
 */
Datum bitcat(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);

	PG_RETURN_VARBIT_P(fc_bit_catenate(fc_arg1, fc_arg2));
}

static VarBit * fc_bit_catenate(VarBit *fc_arg1, VarBit *fc_arg2)
{
	VarBit	   *fc_result;
	int			fc_bitlen1,
				fc_bitlen2,
				fc_bytelen,
				fc_bit1pad,
				fc_bit2shift;
	bits8	   *fc_pr,
			   *fc_pa;

	fc_bitlen1 = VARBITLEN(fc_arg1);
	fc_bitlen2 = VARBITLEN(fc_arg2);

	if (fc_bitlen1 > VARBITMAXLEN - fc_bitlen2)
		ereport(ERROR,
				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
				 errmsg("bit string length exceeds the maximum allowed (%d)",
						VARBITMAXLEN)));
	fc_bytelen = VARBITTOTALLEN(fc_bitlen1 + fc_bitlen2);

	fc_result = (VarBit *) palloc(fc_bytelen);
	SET_VARSIZE(fc_result, fc_bytelen);
	VARBITLEN(fc_result) = fc_bitlen1 + fc_bitlen2;

	/* 复制第一个位字符串 */
	memcpy(VARBITS(fc_result), VARBITS(fc_arg1), VARBITBYTES(fc_arg1));

	/* 复制第二个位字符串 */
	fc_bit1pad = VARBITPAD(fc_arg1);
	if (fc_bit1pad == 0)
	{
		memcpy(VARBITS(fc_result) + VARBITBYTES(fc_arg1), VARBITS(fc_arg2),
			   VARBITBYTES(fc_arg2));
	}
	else if (fc_bitlen2 > 0)
	{
		/* 我们需要移动所有位以适应 */
		fc_bit2shift = BITS_PER_BYTE - fc_bit1pad;
		fc_pr = VARBITS(fc_result) + VARBITBYTES(fc_arg1) - 1;
		for (fc_pa = VARBITS(fc_arg2); fc_pa < VARBITEND(fc_arg2); fc_pa++)
		{
			*fc_pr |= ((*fc_pa >> fc_bit2shift) & BITMASK);
			fc_pr++;
			if (fc_pr < VARBITEND(fc_result))
				*fc_pr = (*fc_pa << fc_bit1pad) & BITMASK;
		}
	}

	/* 此时填充位应该已经为零 */

	return fc_result;
}

/*
 * bitsubstr
 * 从位字符串中检索子字符串。
 * 注意，s是基于1的。
 * SQL草案 6.10 9)
 */
Datum bitsubstr(PG_FUNCTION_ARGS)
{
	PG_RETURN_VARBIT_P(fc_bitsubstring(PG_GETARG_VARBIT_P(0),
									PG_GETARG_INT32(1),
									PG_GETARG_INT32(2),
									false));
}

Datum bitsubstr_no_len(PG_FUNCTION_ARGS)
{
	PG_RETURN_VARBIT_P(fc_bitsubstring(PG_GETARG_VARBIT_P(0),
									PG_GETARG_INT32(1),
									-1, true));
}

static VarBit * fc_bitsubstring(VarBit *fc_arg, int32 fc_s, int32 fc_l, bool fc_length_not_specified)
{
	VarBit	   *fc_result;
	int			fc_bitlen,
				fc_rbitlen,
				fc_len,
				fc_ishift,
				fc_i;
	int32		fc_e,
				fc_s1,
				fc_e1;
	bits8	   *fc_r,
			   *fc_ps;

	fc_bitlen = VARBITLEN(fc_arg);
	fc_s1 = Max(fc_s, 1);
	/* 如果没有上限，使用字符串结尾 */
	if (fc_length_not_specified)
	{
		fc_e1 = fc_bitlen + 1;
	}
	else if (fc_l < 0)
	{
		/* SQL99 规定对于 E < S，即负长度抛出错误 */
		ereport(ERROR,
				(errcode(ERRCODE_SUBSTRING_ERROR),
				 errmsg("negative substring length not allowed")));
		fc_e1 = -1;				/* 消除愚蠢编译器的警告 */
	}
	else if (pg_add_s32_overflow(fc_s, fc_l, &fc_e))
	{
		/*
		 * L 可能大到足以使 S + L 溢出，在这种情况下
		 * 子字符串必须位于字符串的结尾。
		 */
		fc_e1 = fc_bitlen + 1;
	}
	else
	{
		fc_e1 = Min(fc_e, fc_bitlen + 1);
	}
	if (fc_s1 > fc_bitlen || fc_e1 <= fc_s1)
	{
		/* 需要返回一个长度为零的位字符串 */
		fc_len = VARBITTOTALLEN(0);
		fc_result = (VarBit *) palloc(fc_len);
		SET_VARSIZE(fc_result, fc_len);
		VARBITLEN(fc_result) = 0;
	}
	else
	{
		/*
		 * 好吧，我们有一个真正的子字符串，从位置 s1-1 开始，到位置 e1-1 结束
		 */
		fc_rbitlen = fc_e1 - fc_s1;
		fc_len = VARBITTOTALLEN(fc_rbitlen);
		fc_result = (VarBit *) palloc(fc_len);
		SET_VARSIZE(fc_result, fc_len);
		VARBITLEN(fc_result) = fc_rbitlen;
		fc_len -= VARHDRSZ + VARBITHDRSZ;
		/* 我们从字节边界复制吗？ */
		if ((fc_s1 - 1) % BITS_PER_BYTE == 0)
		{
			/* 是的，我们在复制字节 */
			memcpy(VARBITS(fc_result), VARBITS(fc_arg) + (fc_s1 - 1) / BITS_PER_BYTE,
				   fc_len);
		}
		else
		{
			/* 弄清楚我们需要移动序列多少 */
			fc_ishift = (fc_s1 - 1) % BITS_PER_BYTE;
			fc_r = VARBITS(fc_result);
			fc_ps = VARBITS(fc_arg) + (fc_s1 - 1) / BITS_PER_BYTE;
			for (fc_i = 0; fc_i < fc_len; fc_i++)
			{
				*fc_r = (*fc_ps << fc_ishift) & BITMASK;
				if ((++fc_ps) < VARBITEND(fc_arg))
					*fc_r |= *fc_ps >> (BITS_PER_BYTE - fc_ishift);
				fc_r++;
			}
		}

		/* 确保最后一个字节正确地零填充 */
		VARBIT_PAD(fc_result);
	}

	return fc_result;
}

/*
 * bitoverlay
 *	用第二个字符串替换第一个字符串的指定子字符串
 *
 * SQL 标准通过子字符串和连接定义 OVERLAY()。
 * 此代码是标准所述内容的直接实现。
 */
Datum bitoverlay(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_t1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_t2 = PG_GETARG_VARBIT_P(1);
	int			fc_sp = PG_GETARG_INT32(2);	/* 子字符串起始位置 */
	int			fc_sl = PG_GETARG_INT32(3);	/* 子字符串长度 */

	PG_RETURN_VARBIT_P(fc_bit_overlay(fc_t1, fc_t2, fc_sp, fc_sl));
}

Datum bitoverlay_no_len(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_t1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_t2 = PG_GETARG_VARBIT_P(1);
	int			fc_sp = PG_GETARG_INT32(2);	/* 子字符串起始位置 */
	int			fc_sl;

	fc_sl = VARBITLEN(fc_t2);			/* 默认为长度(t2) */
	PG_RETURN_VARBIT_P(fc_bit_overlay(fc_t1, fc_t2, fc_sp, fc_sl));
}

static VarBit * fc_bit_overlay(VarBit *fc_t1, VarBit *fc_t2, int fc_sp, int fc_sl)
{
	VarBit	   *fc_result;
	VarBit	   *fc_s1;
	VarBit	   *fc_s2;
	int			fc_sp_pl_sl;

	/*
	 * 检查可能的整数溢出情况。对于负的 sp，抛出一个
	 * “子字符串长度”错误，因为这是根据规范对 OVERLAY() 的定义应当预期的。
	 */
	if (fc_sp <= 0)
		ereport(ERROR,
				(errcode(ERRCODE_SUBSTRING_ERROR),
				 errmsg("negative substring length not allowed")));
	if (pg_add_s32_overflow(fc_sp, fc_sl, &fc_sp_pl_sl))
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 errmsg("integer out of range")));

	fc_s1 = fc_bitsubstring(fc_t1, 1, fc_sp - 1, false);
	fc_s2 = fc_bitsubstring(fc_t1, fc_sp_pl_sl, -1, true);
	fc_result = fc_bit_catenate(fc_s1, fc_t2);
	fc_result = fc_bit_catenate(fc_result, fc_s2);

	return fc_result;
}

/*
 * bit_count
 *
 * 返回位字符串中设置的位数。
 */
Datum bit_bit_count(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);

	PG_RETURN_INT64(pg_popcount((char *) VARBITS(fc_arg), VARBITBYTES(fc_arg)));
}

/*
 * bitlength, bitoctetlength
 * 返回位字符串的长度
 */
Datum bitlength(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);

	PG_RETURN_INT32(VARBITLEN(fc_arg));
}

Datum bitoctetlength(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);

	PG_RETURN_INT32(VARBITBYTES(fc_arg));
}

/*
 * bit_and
 * 对两个位字符串执行逻辑与操作。
 */
Datum bit_and(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	VarBit	   *fc_result;
	int			fc_len,
				fc_bitlen1,
				fc_bitlen2,
				fc_i;
	bits8	   *fc_p1,
			   *fc_p2,
			   *fc_r;

	fc_bitlen1 = VARBITLEN(fc_arg1);
	fc_bitlen2 = VARBITLEN(fc_arg2);
	if (fc_bitlen1 != fc_bitlen2)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
				 errmsg("cannot AND bit strings of different sizes")));

	fc_len = VARSIZE(fc_arg1);
	fc_result = (VarBit *) palloc(fc_len);
	SET_VARSIZE(fc_result, fc_len);
	VARBITLEN(fc_result) = fc_bitlen1;

	fc_p1 = VARBITS(fc_arg1);
	fc_p2 = VARBITS(fc_arg2);
	fc_r = VARBITS(fc_result);
	for (fc_i = 0; fc_i < VARBITBYTES(fc_arg1); fc_i++)
		*fc_r++ = *fc_p1++ & *fc_p2++;

	/* 不需要填充，因为0与的结果是0 */

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 * bit_or
 * 对两个位字符串执行逻辑或操作。
 */
Datum bit_or(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	VarBit	   *fc_result;
	int			fc_len,
				fc_bitlen1,
				fc_bitlen2,
				fc_i;
	bits8	   *fc_p1,
			   *fc_p2,
			   *fc_r;

	fc_bitlen1 = VARBITLEN(fc_arg1);
	fc_bitlen2 = VARBITLEN(fc_arg2);
	if (fc_bitlen1 != fc_bitlen2)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
				 errmsg("cannot OR bit strings of different sizes")));
	fc_len = VARSIZE(fc_arg1);
	fc_result = (VarBit *) palloc(fc_len);
	SET_VARSIZE(fc_result, fc_len);
	VARBITLEN(fc_result) = fc_bitlen1;

	fc_p1 = VARBITS(fc_arg1);
	fc_p2 = VARBITS(fc_arg2);
	fc_r = VARBITS(fc_result);
	for (fc_i = 0; fc_i < VARBITBYTES(fc_arg1); fc_i++)
		*fc_r++ = *fc_p1++ | *fc_p2++;

	/* 不需要填充，因为0或的结果是0 */

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 * bitxor
 * 对两个位字符串执行逻辑异或操作。
 */
Datum bitxor(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_arg2 = PG_GETARG_VARBIT_P(1);
	VarBit	   *fc_result;
	int			fc_len,
				fc_bitlen1,
				fc_bitlen2,
				fc_i;
	bits8	   *fc_p1,
			   *fc_p2,
			   *fc_r;

	fc_bitlen1 = VARBITLEN(fc_arg1);
	fc_bitlen2 = VARBITLEN(fc_arg2);
	if (fc_bitlen1 != fc_bitlen2)
		ereport(ERROR,
				(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
				 errmsg("cannot XOR bit strings of different sizes")));

	fc_len = VARSIZE(fc_arg1);
	fc_result = (VarBit *) palloc(fc_len);
	SET_VARSIZE(fc_result, fc_len);
	VARBITLEN(fc_result) = fc_bitlen1;

	fc_p1 = VARBITS(fc_arg1);
	fc_p2 = VARBITS(fc_arg2);
	fc_r = VARBITS(fc_result);
	for (fc_i = 0; fc_i < VARBITBYTES(fc_arg1); fc_i++)
		*fc_r++ = *fc_p1++ ^ *fc_p2++;

	/* 不需要填充，因为0异或的结果是0 */

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 * bitnot
 * 对位字符串执行逻辑非操作。
 */
Datum bitnot(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_result;
	bits8	   *fc_p,
			   *fc_r;

	fc_result = (VarBit *) palloc(VARSIZE(fc_arg));
	SET_VARSIZE(fc_result, VARSIZE(fc_arg));
	VARBITLEN(fc_result) = VARBITLEN(fc_arg);

	fc_p = VARBITS(fc_arg);
	fc_r = VARBITS(fc_result);
	for (; fc_p < VARBITEND(fc_arg); fc_p++)
		*fc_r++ = ~*fc_p;

	/* 必须对结果做零填充，因为这里多出的位肯定是1 */
	VARBIT_PAD_LAST(fc_result, fc_r);

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 * bitshiftleft
 * 向左移位（即朝字符串的开头方向）
 */
Datum bitshiftleft(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);
	int32		fc_shft = PG_GETARG_INT32(1);
	VarBit	   *fc_result;
	int			fc_byte_shift,
				fc_ishift,
				fc_len;
	bits8	   *fc_p,
			   *fc_r;

	/* 负移位是向右移位 */
	if (fc_shft < 0)
	{
		/* 防止在取反时发生整数溢出 */
		if (fc_shft < -VARBITMAXLEN)
			fc_shft = -VARBITMAXLEN;
		PG_RETURN_DATUM(DirectFunctionCall2(bitshiftright,
											VarBitPGetDatum(fc_arg),
											Int32GetDatum(-fc_shft)));
	}

	fc_result = (VarBit *) palloc(VARSIZE(fc_arg));
	SET_VARSIZE(fc_result, VARSIZE(fc_arg));
	VARBITLEN(fc_result) = VARBITLEN(fc_arg);
	fc_r = VARBITS(fc_result);

	/* 如果我们将所有位移出，返回一个全零的字符串 */
	if (fc_shft >= VARBITLEN(fc_arg))
	{
		MemSet(fc_r, 0, VARBITBYTES(fc_arg));
		PG_RETURN_VARBIT_P(fc_result);
	}

	fc_byte_shift = fc_shft / BITS_PER_BYTE;
	fc_ishift = fc_shft % BITS_PER_BYTE;
	fc_p = VARBITS(fc_arg) + fc_byte_shift;

	if (fc_ishift == 0)
	{
		/* 特殊情况：我们可以进行内存复制 */
		fc_len = VARBITBYTES(fc_arg) - fc_byte_shift;
		memcpy(fc_r, fc_p, fc_len);
		MemSet(fc_r + fc_len, 0, fc_byte_shift);
	}
	else
	{
		for (; fc_p < VARBITEND(fc_arg); fc_r++)
		{
			*fc_r = *fc_p << fc_ishift;
			if ((++fc_p) < VARBITEND(fc_arg))
				*fc_r |= *fc_p >> (BITS_PER_BYTE - fc_ishift);
		}
		for (; fc_r < VARBITEND(fc_result); fc_r++)
			*fc_r = 0;
	}

	/* 此时填充位应该已经为零 */

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 * bitshiftright
 * 向右移位（即朝字符串的末尾方向）
 */
Datum bitshiftright(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);
	int32		fc_shft = PG_GETARG_INT32(1);
	VarBit	   *fc_result;
	int			fc_byte_shift,
				fc_ishift,
				fc_len;
	bits8	   *fc_p,
			   *fc_r;

	/* 负移位是向左移位 */
	if (fc_shft < 0)
	{
		/* 防止在取反时发生整数溢出 */
		if (fc_shft < -VARBITMAXLEN)
			fc_shft = -VARBITMAXLEN;
		PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
											VarBitPGetDatum(fc_arg),
											Int32GetDatum(-fc_shft)));
	}

	fc_result = (VarBit *) palloc(VARSIZE(fc_arg));
	SET_VARSIZE(fc_result, VARSIZE(fc_arg));
	VARBITLEN(fc_result) = VARBITLEN(fc_arg);
	fc_r = VARBITS(fc_result);

	/* 如果我们将所有位移出，返回一个全零的字符串 */
	if (fc_shft >= VARBITLEN(fc_arg))
	{
		MemSet(fc_r, 0, VARBITBYTES(fc_arg));
		PG_RETURN_VARBIT_P(fc_result);
	}

	fc_byte_shift = fc_shft / BITS_PER_BYTE;
	fc_ishift = fc_shft % BITS_PER_BYTE;
	fc_p = VARBITS(fc_arg);

	/* 将结果的第一部分设为0 */
	MemSet(fc_r, 0, fc_byte_shift);
	fc_r += fc_byte_shift;

	if (fc_ishift == 0)
	{
		/* 特殊情况：我们可以进行内存复制 */
		fc_len = VARBITBYTES(fc_arg) - fc_byte_shift;
		memcpy(fc_r, fc_p, fc_len);
		fc_r += fc_len;
	}
	else
	{
		if (fc_r < VARBITEND(fc_result))
			*fc_r = 0;				/* 初始化第一个字节 */
		for (; fc_r < VARBITEND(fc_result); fc_p++)
		{
			*fc_r |= *fc_p >> fc_ishift;
			if ((++fc_r) < VARBITEND(fc_result))
				*fc_r = (*fc_p << (BITS_PER_BYTE - fc_ishift)) & BITMASK;
		}
	}

	/* 我们可能已经将1移入填充位，因此修正这个问题 */
	VARBIT_PAD_LAST(fc_result, fc_r);

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 * 这在任何标准中都没有定义。我们保留在这里位的自然顺序，
 * 因为这似乎更直观。
 */
Datum bitfromint4(PG_FUNCTION_ARGS)
{
	int32		fc_a = PG_GETARG_INT32(0);
	int32		fc_typmod = PG_GETARG_INT32(1);
	VarBit	   *fc_result;
	bits8	   *fc_r;
	int			fc_rlen;
	int			fc_destbitsleft,
				fc_srcbitsleft;

	if (fc_typmod <= 0 || fc_typmod > VARBITMAXLEN)
		fc_typmod = 1;				/* 默认位长度 */

	fc_rlen = VARBITTOTALLEN(fc_typmod);
	fc_result = (VarBit *) palloc(fc_rlen);
	SET_VARSIZE(fc_result, fc_rlen);
	VARBITLEN(fc_result) = fc_typmod;

	fc_r = VARBITS(fc_result);
	fc_destbitsleft = fc_typmod;
	fc_srcbitsleft = 32;
	/* 丢弃任何不适合的输入位 */
	fc_srcbitsleft = Min(fc_srcbitsleft, fc_destbitsleft);
	/* 在输出中进行符号填充以填充任何多余的字节 */
	while (fc_destbitsleft >= fc_srcbitsleft + 8)
	{
		*fc_r++ = (bits8) ((fc_a < 0) ? BITMASK : 0);
		fc_destbitsleft -= 8;
	}
	/* 存储第一个小数字节 */
	if (fc_destbitsleft > fc_srcbitsleft)
	{
		unsigned int fc_val = (unsigned int) (fc_a >> (fc_destbitsleft - 8));

		/* 强制符号填充，以防编译器将 >> 实现为零填充 */
		if (fc_a < 0)
			fc_val |= ((unsigned int) -1) << (fc_srcbitsleft + 8 - fc_destbitsleft);
		*fc_r++ = (bits8) (fc_val & BITMASK);
		fc_destbitsleft -= 8;
	}
	/* 现在 srcbitsleft 和 destbitsleft 是相同的，不需要同时跟踪 */
	/* 存储完整字节 */
	while (fc_destbitsleft >= 8)
	{
		*fc_r++ = (bits8) ((fc_a >> (fc_destbitsleft - 8)) & BITMASK);
		fc_destbitsleft -= 8;
	}
	/* 存储最后一个小数字节 */
	if (fc_destbitsleft > 0)
		*fc_r = (bits8) ((fc_a << (8 - fc_destbitsleft)) & BITMASK);

	PG_RETURN_VARBIT_P(fc_result);
}

Datum bittoint4(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);
	uint32		fc_result;
	bits8	   *fc_r;

	/* 检查位字符串是否过长 */
	if (VARBITLEN(fc_arg) > sizeof(fc_result) * BITS_PER_BYTE)
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 errmsg("integer out of range")));

	fc_result = 0;
	for (fc_r = VARBITS(fc_arg); fc_r < VARBITEND(fc_arg); fc_r++)
	{
		fc_result <<= BITS_PER_BYTE;
		fc_result |= *fc_r;
	}
	/* 现在移动结果以考虑末尾的填充 */
	fc_result >>= VARBITPAD(fc_arg);

	PG_RETURN_INT32(fc_result);
}

Datum bitfromint8(PG_FUNCTION_ARGS)
{
	int64		fc_a = PG_GETARG_INT64(0);
	int32		fc_typmod = PG_GETARG_INT32(1);
	VarBit	   *fc_result;
	bits8	   *fc_r;
	int			fc_rlen;
	int			fc_destbitsleft,
				fc_srcbitsleft;

	if (fc_typmod <= 0 || fc_typmod > VARBITMAXLEN)
		fc_typmod = 1;				/* 默认位长度 */

	fc_rlen = VARBITTOTALLEN(fc_typmod);
	fc_result = (VarBit *) palloc(fc_rlen);
	SET_VARSIZE(fc_result, fc_rlen);
	VARBITLEN(fc_result) = fc_typmod;

	fc_r = VARBITS(fc_result);
	fc_destbitsleft = fc_typmod;
	fc_srcbitsleft = 64;
	/* 丢弃任何不适合的输入位 */
	fc_srcbitsleft = Min(fc_srcbitsleft, fc_destbitsleft);
	/* 在输出中进行符号填充以填充任何多余的字节 */
	while (fc_destbitsleft >= fc_srcbitsleft + 8)
	{
		*fc_r++ = (bits8) ((fc_a < 0) ? BITMASK : 0);
		fc_destbitsleft -= 8;
	}
	/* 存储第一个小数字节 */
	if (fc_destbitsleft > fc_srcbitsleft)
	{
		unsigned int fc_val = (unsigned int) (fc_a >> (fc_destbitsleft - 8));

		/* 强制符号填充，以防编译器将 >> 实现为零填充 */
		if (fc_a < 0)
			fc_val |= ((unsigned int) -1) << (fc_srcbitsleft + 8 - fc_destbitsleft);
		*fc_r++ = (bits8) (fc_val & BITMASK);
		fc_destbitsleft -= 8;
	}
	/* 现在 srcbitsleft 和 destbitsleft 是相同的，不需要同时跟踪 */
	/* 存储完整字节 */
	while (fc_destbitsleft >= 8)
	{
		*fc_r++ = (bits8) ((fc_a >> (fc_destbitsleft - 8)) & BITMASK);
		fc_destbitsleft -= 8;
	}
	/* 存储最后一个小数字节 */
	if (fc_destbitsleft > 0)
		*fc_r = (bits8) ((fc_a << (8 - fc_destbitsleft)) & BITMASK);

	PG_RETURN_VARBIT_P(fc_result);
}

Datum bittoint8(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg = PG_GETARG_VARBIT_P(0);
	uint64		fc_result;
	bits8	   *fc_r;

	/* 检查位字符串是否过长 */
	if (VARBITLEN(fc_arg) > sizeof(fc_result) * BITS_PER_BYTE)
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 errmsg("bigint out of range")));

	fc_result = 0;
	for (fc_r = VARBITS(fc_arg); fc_r < VARBITEND(fc_arg); fc_r++)
	{
		fc_result <<= BITS_PER_BYTE;
		fc_result |= *fc_r;
	}
	/* 现在移动结果以考虑末尾的填充 */
	fc_result >>= VARBITPAD(fc_arg);

	PG_RETURN_INT64(fc_result);
}


/*
 * 确定位字符串 S1 中 S2 的位置（基于1的字符串）。
 * 如果 S2 不出现在 S1 中，则此函数返回 0。
 * 如果 S2 的长度为 0，则此函数返回 1。
 * 与其他数据类型的位置（POSITION()）函数在用法上兼容。
 */
Datum bitposition(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_str = PG_GETARG_VARBIT_P(0);
	VarBit	   *fc_substr = PG_GETARG_VARBIT_P(1);
	int			fc_substr_length,
				fc_str_length,
				fc_i,
				fc_is;
	bits8	   *fc_s,				/* 子字符串的指针 */
			   *fc_p;				/* 字符串的指针 */
	bits8		fc_cmp,			/* 移位的子字符串字节以进行比较 */
				fc_mask1,			/* 向右移位的子字符串字节掩码 */
				fc_mask2,			/* 向左移位的子字符串字节掩码 */
				fc_end_mask,		/* 最后一个子字符串字节的填充掩码 */
				fc_str_mask;		/* 最后一个字符串字节的填充掩码 */
	bool		fc_is_match;

	/* 获取子字符串长度 */
	fc_substr_length = VARBITLEN(fc_substr);
	fc_str_length = VARBITLEN(fc_str);

	/* 字符串长度为零或子字符串长度超过字符串，返回 0 */
	if ((fc_str_length == 0) || (fc_substr_length > fc_str_length))
		PG_RETURN_INT32(0);

	/* 零长度的子字符串意味着返回 1 */
	if (fc_substr_length == 0)
		PG_RETURN_INT32(1);

	/* 初始化填充掩码 */
	fc_end_mask = BITMASK << VARBITPAD(fc_substr);
	fc_str_mask = BITMASK << VARBITPAD(fc_str);
	for (fc_i = 0; fc_i < VARBITBYTES(fc_str) - VARBITBYTES(fc_substr) + 1; fc_i++)
	{
		for (fc_is = 0; fc_is < BITS_PER_BYTE; fc_is++)
		{
			fc_is_match = true;
			fc_p = VARBITS(fc_str) + fc_i;
			fc_mask1 = BITMASK >> fc_is;
			fc_mask2 = ~fc_mask1;
			for (fc_s = VARBITS(fc_substr);
				 fc_is_match && fc_s < VARBITEND(fc_substr); fc_s++)
			{
				fc_cmp = *fc_s >> fc_is;
				if (fc_s == VARBITEND(fc_substr) - 1)
				{
					fc_mask1 &= fc_end_mask >> fc_is;
					if (fc_p == VARBITEND(fc_str) - 1)
					{
						/* 检查字符串剩余部分是否足够 */
						if (fc_mask1 & ~fc_str_mask)
						{
							fc_is_match = false;
							break;
						}
						fc_mask1 &= fc_str_mask;
					}
				}
				fc_is_match = ((fc_cmp ^ *fc_p) & fc_mask1) == 0;
				if (!fc_is_match)
					break;
				/* 移动到下一个字节 */
				fc_p++;
				if (fc_p == VARBITEND(fc_str))
				{
					fc_mask2 = fc_end_mask << (BITS_PER_BYTE - fc_is);
					fc_is_match = fc_mask2 == 0;
#if 0
					elog(DEBUG4, "S. %d %d em=%2x sm=%2x r=%d",
						 i, is, end_mask, mask2, is_match);
#endif
					break;
				}
				fc_cmp = *fc_s << (BITS_PER_BYTE - fc_is);
				if (fc_s == VARBITEND(fc_substr) - 1)
				{
					fc_mask2 &= fc_end_mask << (BITS_PER_BYTE - fc_is);
					if (fc_p == VARBITEND(fc_str) - 1)
					{
						if (fc_mask2 & ~fc_str_mask)
						{
							fc_is_match = false;
							break;
						}
						fc_mask2 &= fc_str_mask;
					}
				}
				fc_is_match = ((fc_cmp ^ *fc_p) & fc_mask2) == 0;
			}
			/* 我们找到匹配项了吗？ */
			if (fc_is_match)
				PG_RETURN_INT32(fc_i * BITS_PER_BYTE + fc_is + 1);
		}
	}
	PG_RETURN_INT32(0);
}


/*
 * bitsetbit
 *
 * 给定一个 'bit' 类型的实例，创建一个新的实例，
 * 将第 N 位设置为给定值。
 *
 * 位位置从左到右以零基的方式指定
 * 一致与其他 get_bit 和 set_bit 函数，但
 * 与标准的子字符串、位置、覆盖函数不一致
 */
Datum bitsetbit(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	int32		fc_n = PG_GETARG_INT32(1);
	int32		fc_newBit = PG_GETARG_INT32(2);
	VarBit	   *fc_result;
	int			fc_len,
				fc_bitlen;
	bits8	   *fc_r,
			   *fc_p;
	int			fc_byteNo,
				fc_bitNo;

	fc_bitlen = VARBITLEN(fc_arg1);
	if (fc_n < 0 || fc_n >= fc_bitlen)
		ereport(ERROR,
				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
				 errmsg("bit index %d out of valid range (0..%d)",
						fc_n, fc_bitlen - 1)));

	/*
	 * 安全检查！
	 */
	if (fc_newBit != 0 && fc_newBit != 1)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("new bit must be 0 or 1")));

	fc_len = VARSIZE(fc_arg1);
	fc_result = (VarBit *) palloc(fc_len);
	SET_VARSIZE(fc_result, fc_len);
	VARBITLEN(fc_result) = fc_bitlen;

	fc_p = VARBITS(fc_arg1);
	fc_r = VARBITS(fc_result);

	memcpy(fc_r, fc_p, VARBITBYTES(fc_arg1));

	fc_byteNo = fc_n / BITS_PER_BYTE;
	fc_bitNo = BITS_PER_BYTE - 1 - (fc_n % BITS_PER_BYTE);

	/*
	 * 更新字节。
	 */
	if (fc_newBit == 0)
		fc_r[fc_byteNo] &= (~(1 << fc_bitNo));
	else
		fc_r[fc_byteNo] |= (1 << fc_bitNo);

	PG_RETURN_VARBIT_P(fc_result);
}

/*
 * bitgetbit
 *
 * 返回位数组第 N 位的值（0 或 1）。
 *
 * 位位置从左到右以零基的方式指定
 * 一致与其他 get_bit 和 set_bit 函数，但
 * 与标准的子字符串、位置、覆盖函数不一致
 */
Datum bitgetbit(PG_FUNCTION_ARGS)
{
	VarBit	   *fc_arg1 = PG_GETARG_VARBIT_P(0);
	int32		fc_n = PG_GETARG_INT32(1);
	int			fc_bitlen;
	bits8	   *fc_p;
	int			fc_byteNo,
				fc_bitNo;

	fc_bitlen = VARBITLEN(fc_arg1);
	if (fc_n < 0 || fc_n >= fc_bitlen)
		ereport(ERROR,
				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
				 errmsg("bit index %d out of valid range (0..%d)",
						fc_n, fc_bitlen - 1)));

	fc_p = VARBITS(fc_arg1);

	fc_byteNo = fc_n / BITS_PER_BYTE;
	fc_bitNo = BITS_PER_BYTE - 1 - (fc_n % BITS_PER_BYTE);

	if (fc_p[fc_byteNo] & (1 << fc_bitNo))
		PG_RETURN_INT32(1);
	else
		PG_RETURN_INT32(0);
}
